package com.test.controller;

import com.alibaba.fastjson.JSONArray;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

import static com.test.controller.CalculationUtils.equalization;
import static com.test.controller.CalculationUtils.negativeNumber;

/**
 * Created by Administrator on 2017/4/25.
 */
@Controller
public class PowerFee {

    @RequestMapping("getCity")
    public String getCity(HttpServletRequest request, String year, String month){
        List<Object[]> current = DataUtils.getCurrentData();
        List<Object[]> last = DataUtils.getLastData();
        Map<Integer, Integer> currentMap = conversion(current);
        Map<Integer, Integer> lastMap = conversion(last);
        JSONArray menuJSON = new JSONArray();
        for(String cityName : DataUtils.cityNames()){
            menuJSON.add(cityName);
        }
        JSONArray currentJSON = new JSONArray();
        JSONArray lastJSON = new JSONArray();
        currentJSON = conv(currentMap, currentJSON);
        lastJSON = conv(lastMap, lastJSON);
        //当前值
        List<Integer> currentList = new ArrayList<Integer>();
        currentList = convInteger(currentMap, currentList);
        //去年值
        List<Integer> lastList = new ArrayList<Integer>();
        lastList = convInteger(lastMap, lastList);

        List<Integer> diff = difference(currentList, lastList);

        JSONArray diffJSON = new JSONArray();
        for(Integer integer : diff){
            diffJSON.add(integer);
        }
        JSONArray increaseJSON = increase(lastList, diff);

        int max = 100;
        int min = 0;
        max = max(currentList, lastList);
        min = min(currentList, lastList, diff);
        int equalization = 5;
        int maxZ = max;

        max = echartsMax(max, min);
        equalization = max/5;
        min = echartsMin(min, equalization);
        maxZ = negativeNumber(maxZ, equalization);
        JSONArray equJSON = new JSONArray();
        equJSON.add(equalization);

        List<Integer> increaseList = increaseInteger(lastList, diff);
        Collections.sort(increaseList);
        int incrMax = 100;
        int incrMin = 0;
        if(increaseList.size()>0){
            incrMax = increaseList.get(increaseList.size()-1);
            incrMin = increaseList.get(0);
        }
        int incrMaxZ = incrMax;
        incrMax = echartsMax(incrMax, incrMin);

        equalization = incrMax/5;
        incrMin = echartsMin(incrMin, equalization);
        incrMaxZ = negativeNumber(incrMaxZ, equalization);

        JSONArray incrEquJSON = new JSONArray();
        incrEquJSON.add(equalization);

        request.setAttribute("menus", menuJSON.toString());
        request.setAttribute("currentJSON", currentJSON.toString());
        request.setAttribute("lastJSON", lastJSON.toString());
        request.setAttribute("diffJSON", diffJSON.toString());
        request.setAttribute("increaseJSON", increaseJSON.toString());
        request.setAttribute("year", year);
        request.setAttribute("years", DateUtils.getYears());
        request.setAttribute("months", DateUtils.getMonths());
        request.setAttribute("max", maxZ);
        request.setAttribute("min", (-min));
        request.setAttribute("equalization", equJSON.toString());
        request.setAttribute("incrEquJSON", incrEquJSON.toString());
        request.setAttribute("incrMaxZ", incrMaxZ);
        request.setAttribute("incrMin", (-incrMin));
        return "city";
    }

    public int echartsMin(int min, int equalization){
        if(min < 0){
            min = Math.abs(min);
            min = negativeNumber(min, equalization);
        }
        return min;
    }
    public int echartsMax(int max, int min){
        if(min<0){
            max = max-min;
        }
        int number = CalculationUtils.numberOfBits(max);
        max = equalization(max, number);
        return max;
    }

    private int max(List<Integer> currentList, List<Integer> lastList){
        Collections.sort(currentList);
        Collections.sort(lastList);
        int max = 0;
        int currentMax = 0;
        int lastMax = 0;
        if(currentList.size()>0){
            currentMax = currentList.get(currentList.size()-1);
        }
        if(lastList.size() > 0){
            lastMax = lastList.get(lastList.size() - 1);
        }

        max = (currentMax > lastMax) ? currentMax : lastMax;
        return max;
    }

    private int min(List<Integer> currentList, List<Integer> lastList, List<Integer> diff){
        Collections.sort(currentList);
        Collections.sort(lastList);
        Collections.sort(diff);
        int min = 0;
        int currentMin = 0;
        int lastMin = 0;
        int diffMin = 0;
        if(currentList.size()>0){
            currentMin = currentList.get(0);
        }
        if(lastList.size() > 0){
            lastMin = lastList.get(0);
        }
        if(diff.size()>0){
            diffMin = diff.get(0);
        }
        min = (currentMin < lastMin) ? currentMin : lastMin;
        min = (min < diffMin) ? min : diffMin;
        return min;
    }
    private Map<Integer, Integer> conversion(List<Object[]> list){
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for(Object[] object : list){
            map.put(Integer.parseInt(String.valueOf(object[0])), Integer.parseInt(String.valueOf(object[1])));
        }
        return map;
    }

    private JSONArray conv(Map<Integer, Integer> map, JSONArray json){
        List<Integer> cityIds = DataUtils.cityIds();
        for(Integer id : cityIds){
            if(map.containsKey(id)){
                json.add(map.get(id));
            }else {
                json.add(0);
            }
        }
        return json;
    }

    private List<Integer> convInteger(Map<Integer, Integer> map, List<Integer> list){
        List<Integer> cityIds = DataUtils.cityIds();
        for(Integer id : cityIds){
            if(map.containsKey(id)){
                list.add(map.get(id));
            }else {
                list.add(0);
            }
        }
        return list;
    }

    private List<Integer> difference(List<Integer> current, List<Integer> last){
        List<Integer> diff = new ArrayList<Integer>();
        for(int i =0; i<current.size(); i++){
            diff.add(current.get(i) - last.get(i));
        }
        return diff;
    }

    public JSONArray increase(List<Integer> lasts, List<Integer> diffs){
        JSONArray incrJSON = new JSONArray();
        for(int i=0; i<lasts.size(); i++){
            BigDecimal last = new BigDecimal(lasts.get(i));
            BigDecimal diff = new BigDecimal(diffs.get(i));
            BigDecimal incr = diff.divide(last, 3, 4);

            System.out.println(incr + " "+aDecimal(incr.doubleValue()*100));
            incrJSON.add(aDecimal(incr.doubleValue()*100));

        }

        return incrJSON;
    }

    public List<Integer> increaseInteger(List<Integer> lasts, List<Integer> diffs){
        List<Integer> list = new ArrayList<Integer>();
        double temp = 0;
        for(int i=0; i<lasts.size(); i++){
            BigDecimal last = new BigDecimal(lasts.get(i));
            BigDecimal diff = new BigDecimal(diffs.get(i));
            BigDecimal incr = diff.divide(last, 3, 4);
            double incrD = incr.doubleValue()*100;
            if(incrD>=0){
                temp = Math.ceil(incrD);
            }else {
                temp = Math.floor(incrD);
            }
            String string = String.valueOf(temp);
            string = string.substring(0, string.indexOf("."));
            list.add(Integer.parseInt(string));

        }

        return list;
    }

    public String aDecimal(Double d){
        if(d == null){
            return null;
        }
        String num = d.toString();
        num = num.substring(0, num.indexOf(".", 0) + 2);
        return num;
    }

}
